package com.hoshiicloud.goods.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.conditions.Wrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.hoshiicloud.common.aop.Logable;
import com.hoshiicloud.common.exception.CommonError;
import com.hoshiicloud.common.exception.ServiceException;
import com.hoshiicloud.common.utils.tree.GoodsCategoryWithGoodNumTree;
import com.hoshiicloud.common.utils.tree.Menu;
import com.hoshiicloud.common.utils.tree.TreeParserUtils;
import com.hoshiicloud.goods.entity.goods.GoodsCategory;
import com.hoshiicloud.goods.feign.IdGeneratorService;
import com.hoshiicloud.goods.mapper.goods.GoodsCategoryMapper;
import com.hoshiicloud.goods.param.goods.GoodsCategoryUpdateParam;
import com.hoshiicloud.goods.service.GoodsCategoryService;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cache.annotation.CacheEvict;
import org.springframework.cache.annotation.Cacheable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.time.LocalDateTime;
import java.util.List;

/**
 * <p>
 * 商品类目表 服务实现类
 * </p>
 *
 * @author zhangshuhu
 * @since 2019-06-04
 */
@Slf4j
@Service
public class GoodsCategoryServiceImpl extends ServiceImpl<GoodsCategoryMapper, GoodsCategory> implements GoodsCategoryService {

    @Autowired
    private IdGeneratorService idGeneratorService;

    @Autowired
    private GoodsCategoryMapper goodsCategoryMapper;

    @Override
    @Logable(authName = "商品管理-商品类目表管理-分页查询商品类目表")
    @Cacheable(cacheNames = "GoodsCategory", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#key")
    public Page<GoodsCategory> getPage(Page<GoodsCategory> page, Wrapper<GoodsCategory> queryWrapper, String key) {
        baseMapper.selectPage(page, queryWrapper);
        return page;
    }

    @Override
    @Cacheable(cacheNames = "GoodsCategory", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#id")
    @Logable(authName = "商品管理-商品类目表-查询商品类目表 ")
    public GoodsCategory getById(Long id) {
        return baseMapper.selectById(id);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "GoodsCategory", allEntries = true)
    @Logable(authName = "商品管理-商品类目表-新增商品类目表")
    public boolean save(GoodsCategory entity) {
        //判断数据是否异常
        this.judgeIsRight(entity,1);

        // 新增数据
        entity.setId(this.getId());
        entity.setLeaf(0);
        entity.setCode(this.getCode(entity));
        entity.setCreatedTime(LocalDateTime.now());
        try{
            int row = baseMapper.insert(entity);
            if (row <= 0) {
                throw new ServiceException(CommonError.error("新增失败"));
            }
        }catch (Exception e){
            log.error("商品类目插入异常",e);
            if(e.getMessage().contains("goods_category_code_udx")){
                throw new ServiceException("系统生成类目编码重复,请重新提交");
            }
            throw new ServiceException(e.getMessage());
        }

        if (entity.getLevel() > 1) {
            GoodsCategory parent = new GoodsCategory();
            parent.setId(entity.getParentId());
            parent.setLeaf(1);
            baseMapper.updateById(parent);
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "GoodsCategory", allEntries = true)
    @Logable(authName = "商品管理-商品类目表管理-修改商品类目表")
    public boolean updateById(GoodsCategory entity) {
        //判断数据是否异常
        this.judgeIsRight(entity,2);
        // 更新数据
        entity.setUpdatedTime(LocalDateTime.now());
        int row = baseMapper.updateById(entity);
        if (row <= 0) {
            throw new ServiceException(CommonError.error("修改失败"));
        }
        return true;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    @CacheEvict(cacheNames = "GoodsCategory", allEntries = true)
    @Logable(authName = "商品管理-商品类目表管理-删除商品类目表")
    public boolean deleteById(Long id) {

        // 根据id查询数据
        GoodsCategory entity = this.getById(id);
        if (entity == null) {
            throw new ServiceException("删除商品类目表异常，无法找到商品类目表记录");
        }

        //进行删除操作
        entity.setUpdatedTime(LocalDateTime.now());
        entity.setDeleted(1);
        int row = baseMapper.updateById(entity);
        if (row <= 0) {
            throw new ServiceException(CommonError.error("删除失败"));
        }
        return true;
    }

    @Override
    @Cacheable(cacheNames = "GoodsCategory", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#key")
    @Logable(authName = "商品管理-商品类目表管理-根据id集合查询商品类目表")
    public List<GoodsCategory> getByIds(List<Long> ids, String key) {
        return baseMapper.selectBatchIds(ids);
    }

    @Override
    @Cacheable(cacheNames = "GoodsCategory", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#companyId")
    @Logable(authName = "商品管理-商品类目表管理-获取商品类目树状数据（不查询禁用的）")
    public List<Menu> getCategorys(Long companyId) {
        List<Menu> list = goodsCategoryMapper.getCategorys(companyId);
        return TreeParserUtils.getTreeList("0", list);
    }

    @Override
    @Cacheable(cacheNames = "GoodsCategory", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#companyId")
    @Logable(authName = "商品管理-商品类目表管理-获取商品类目（含商品数量）树状数据")
    public List<GoodsCategoryWithGoodNumTree> getCategorysWithGoodsNum(Long companyId) {
        List<GoodsCategoryWithGoodNumTree> list = goodsCategoryMapper.listGoodsCategoryWithGoodsNums(companyId);
        return TreeParserUtils.getTreeList("0", list);
    }

    @Override
    @CacheEvict(cacheNames = "GoodsCategory", allEntries = true)
    @Logable(authName = "商品管理-商品类目表管理-修改启用禁用状态")
    @Transactional(rollbackFor = Exception.class)
    public boolean updateStatus(GoodsCategory entity) {
        GoodsCategory gc = this.getById(entity.getId());
        goodsCategoryMapper.updateById(entity);
        if(gc.getLevel() == 2){
            goodsCategoryMapper.updateStatusChildren(entity);
        }else if(gc.getLevel() == 1){
            goodsCategoryMapper.updateStatusChildren(entity);
            List<GoodsCategory> childrenChildrenIds = goodsCategoryMapper.selectChildrenChildren(entity);
            this.updateBatchById(childrenChildrenIds);
        }
        return true;
    }

    @Override
    @Cacheable(cacheNames = "GoodsCategory", key = "#root.targetClass.simpleName+':'+#root.methodName+':'+#companyId")
    @Logable(authName = "商品管理-商品类目表管理-获取商品类目树状数据（含禁用的）")
    public List<Menu> getCategorys3(Long companyId) {
        List<Menu> list = goodsCategoryMapper.getCategorys3(companyId);
        return TreeParserUtils.getTreeList("0", list);
    }


    private void judgeIsRight(GoodsCategory goodsCategory,int type){
        if(type == 1){
            if (goodsCategory.getLevel() > 3) {
                throw new ServiceException("类目等级最多为三级");
            }
        }

        if ( type ==1 && goodsCategory.getLevel() == 3) {
            if ( null == goodsCategory.getImportTaxes()) {
                throw new ServiceException("进口税率未填写");
            }
            return;
        }
        if (type ==2) {
            GoodsCategory old = baseMapper.selectById(goodsCategory.getId());
            if(old.getLevel() == 3){
                if ( null == goodsCategory.getImportTaxes()) {
                    throw new ServiceException("进口税率未填写");
                }
            }

        }

    }

    private Long getCode(GoodsCategory entity){
          Long maxCode = goodsCategoryMapper.getMaxCodeByCompanyIdAndParentId(entity.getCompanyId(),entity.getParentId());
          if(null == maxCode){
              if(entity.getLevel() == 1){
                  return 1001L;
              }else{
                  GoodsCategory par = this.getById(entity.getParentId());
                  if(entity.getLevel() == 2){
                      return  Long.valueOf(par.getCode().toString()+"0001");
                  }else{
                      return  Long.valueOf(par.getCode().toString()+"00001");
                  }
              }
          }else{
              return (maxCode+1L);
          }
    }

    private Long getId(){
        String id = idGeneratorService.queryGeneratorId();
        if (StrUtil.isBlank(id)) {
            throw new ServiceException(CommonError.error("主键ID生成失败"));
        }
        return Long.valueOf(id);
    }

    /**
     * 查询类目内容
     *
     * @param categoryContextQueryStr String
     * @return String
     */
    @Override
    public String selectcategoryContext(String categoryContextQueryStr) {
        return goodsCategoryMapper.selectcategoryContext(categoryContextQueryStr);
    }

}
